

SNFAuc = { }

SMHistory = { }

local SMLastQueryCounts = { }
SMLastQueryData = { }

local scanContext = { }

local currentPage = 0
local auctionCallback = nil
local inScan = false
local readOnce = false

local auctionReady = false

function SNFAuc:InterfaceOn()
	auctionReady = true
	SMDEBUG(4, "Auction ready")
end

function SNFAuc:InterfaceOff()
	auctionReady = false
	SMDEBUG(4, "Auction no longer ready")
end

function SNFAuc:UpdateList()
	SMDEBUG(2, "Auction list updated")
	if (inScan) then SNFAuc:ReadPage() end
end

function SNFAuc:UpdateOwned()
	SMDEBUG(4, "Auction owned updated")
end

function SNFAuc:UpdateBids()
	SMDEBUG(4, "Auction bids updated")
end

function SNFAuc:CheckAuctionCallback()

	SMDEBUG(5, "CheckAuctionCallback")

	if auctionCallback ~= nil then
		auctionCallback()
	end
end

local function GetAmountString(copper)
	if not copper then return "nil" end

	local silver = copper / 100;  copper = copper % 100
	local gold = silver / 100;  silver = silver % 100

	local string = ""
	if (copper > 0) then string = (" %dc"):format(copper)..string end
	if (silver > 0) then string = (" %ds"):format(silver)..string end
	if (gold > 0)   then string = (" %dg"):format(gold)..string end

	return string;
--	return ("%dg %ds %dc"):format(copper / 100 / 100, (copper / 100) % 100, copper % 100)
end

local function TriggerNextPage()

	if (not scanContext["name"]) then
		SMDEBUG(1, "You must provide a valid name to search auctions on")
		return
	end
--	SMDEBUG(4, "TriggerNextPage: "..(currentPage or "nil"))

	if (not auctionReady) then
		SMDEBUG(1, "Auction house closed during query");
		auctionCallback = nil
		return
	end

	local canQuery,canQueryAll = CanSendAuctionQuery()


	if canQuery then
		auctionCallback = nil
		SMDEBUG(2, "Triggering scan for "..scanContext["name"].." classIndex is "..(scanContext["classIndex"] or "nil")..
				" subclassIndex is "..(scanContext["subclassIndex"] or "nil"))

		QueryAuctionItems(	scanContext["name"],
					scanContext["minLevel"],
					scanContext["maxLevel"],
					scanContext["invTypeIndex"],
					tonumber(scanContext["classIndex"] or 0),
					tonumber(scanContext["subclassIndex"] or 0),
					currentPage,
					scanContext["isUsable"],
					scanContext["qualityIndex"],
					scanContext["getAll"])
		readOnce = true -- using as a guardian as update list seems to be called more than once.
	else
--		SMDEBUG(4, "Auction not ready, setting callback")
		auctionCallback = TriggerNextPage
	end
end

local function StartScan()

	SMDEBUG(1, "Starting scan for "..scanContext["name"].." classIndex is "..(scanContext["classIndex"] or "nil")..
			" subclassIndex is "..(scanContext["subclassIndex"] or "nil"))
	inScan = true
	TriggerNextPage()
end

local function clearScanContext()
	scanContext["name"] = ""
	scanContext["minLevel"] = 0
	scanContext["maxLevel"] = 0
	scanContext["invTypeIndex"] = 0
	scanContext["classIndex"] = 0
	scanContext["subclassIndex"] = 0
	scanContext["isUsable"]= 0
	scanContext["qualityIndex"] = 0
	scanContext["getAll"] = 0
end

local function ResetScan()

	currentPage = 0
	SMLastQueryCounts = { }
	SMLastQueryData = { }
	clearScanContext()
end

function SNFAuc:GetAuctioningGlyphs()

	if (not auctionReady) then
		SMDEBUG(1, "You must open the auction house before using this feature.")
		return
	end

	ResetScan()
	scanContext["name"] = "Glyph of"
	scanContext["classIndex"] = 5 -- Should be glyphs
	scanContext["subclassIndex"] = 10 -- play with druid glyphs for now, keeps tests faster :)

	StartScan()
end

function SNFAuc:ParseAuction(data)

	if (SMHistory ~= nil and data["name"] ~= nil) then
		SMHistory[data["name"]] = (SMHistory[data["name"]] or 0) + 1
		SMLastQueryCounts[data["name"]] = (SMLastQueryCounts[data["name"]] or 0) + 1
	end
	if (SMLastQueryData ~= nil) then
		tinsert(SMLastQueryData, data)
	end
end


function SNFAuc:ReadPage()

	if (not readOnce) then
		SMDEBUG(4, "ReadPage called when readOnce is false! - Skipping read")
		return
	end
	SMDEBUG(4, "ReadPage: "..(currentPage or "nil"))

	readOnce = false
	local i = 1

	name = " "

	while (name ~= nil) do
		local aname, texture, count, quality, canUse, level,
			minBid, minIncrement, buyoutPrice, bidAmount,
			highBidder, owner, saleStatus  = GetAuctionItemInfo("list", i);

		name = aname

		if (name ~= nil) then
			i = i + 1
			local data = { }
			data["name"] = aname
			data["count"] = count
			data["minBid"] = minBid
			data["minIncrement"] = minIncrement
			data["buyoutPrice"] = buyoutPrice
			data["bidAmount"] = bidAmount
			data["highBidder"] = highBidder
			data["owner"] = owner
			data["saleStatus"] = saleStatus
			SNFAuc:ParseAuction(data)
		end
	end


	if i < 2 then
		auctionCallback = nil
		SMDEBUG(1, "Done with scan\n")
		SNFAuc:SummarizeLastQueryCounts()
		inScan = false
		return
	else
		SMDEBUG(2, "Found "..((i or 0)-1).. " items on page "..(currentPage or "nil"))
	end

	if currentPage > 100 then
		auctionCallback = nil
		SMDEBUG(1, "> 100 pages: Safety abort")
		return
	end
	currentPage = currentPage + 1

	SMDEBUG(3, "Auction Page updated to "..currentPage)
	TriggerNextPage()
end

function SNFAuc:SummarizeLastQueryCounts()

	for it, num in pairs(SMLastQueryCounts) do
		SMDEBUG(2, "Item Name: "..(it or "nil").." counted: "..(num or "nil").." times")
	end
	if SMLastQueryData ~= nil then
		SMDEBUG(2, "Total items recorded: "..(#SMLastQueryData or "nil"))
	end
end

function SNFAuc:AnalyzeQueryCounts()

	local checkOnlyWhatICanMake = true

	local listMin = { }
	local largestMinBidNum = 0
	local largestMinBidName = "UNKNOWN"
	local smallestBidNum = 999999999
	local smallestBidName = "UNKNOWN"
--	local fewestAuctionsNum = 9999
--	local fewestAuctionsName = "UNKNOWN"
	local listSaleStatus = { }

	local nameList = { }


--			data["name"] = aname
--			data["count"] = count
--			data["minBid"] = minBid
--			data["minIncrement"] = minIncrement
--			data["buyoutPrice"] = buyoutPrice
--			data["bidAmount"] = bidAmount
--			data["highBidder"] = highBidder
--			data["owner"] = owner
--				data["saleStatus"] = saleStatus


	for _, data in ipairs(SMLastQueryData) do
		if data and data["name"] then

			nameList[data["name"]] = true
			local n = data["name"]
			if (not listMin[n]) then listMin[n] = 99999999 end
			if (not listSaleStatus[n]) then listSaleStatus[n] = { } end

			if data["minBid"] and data["minBid"] < listMin[n] then
				listMin[n] = data["minBid"]

				if data["minBid"] < smallestBidNum then
					smallestBidNum = data["minBid"]
					smallestBidName = n
				end
			end
		end
	end
	for n, _ in pairs(nameList) do

		if SMItemSource:CanIAcquire(n) then
			if listMin[n] and listMin[n] > largestMinBidNum then
				largestMinBidNum = listMin[n]
				largestMinBidName = n
			end
			if listMin[n] and listMin[n] > (6 *100 *100)  then -- 6g
				SMDEBUG(1, "Item "..(n or "nil").." has a min bid more than 6g")
			end
		else
			SMDEBUG(2, "Can't make or acquire "..(n or "nil"))
		end
	end

	for name, _ in pairs(nameList) do
		if SMItemSource:CanIAcquire(name) then
			SMDEBUG(2, "Can make: "..(name or "nil").." min Bid: "..GetAmountString(listMin[name]))
		end
	end
	SMDEBUG(1, "Smallest price overall: "..GetAmountString(smallestBidNum).." for "..(smallestBidName or "nil"))
	SMDEBUG(1, "Largest price overall: "..GetAmountString(largestMinBidNum).." for "..(largestMinBidName or "nil"))
end